package com.sinosoft.brokerchannel.base.utile.token;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.sinosoft.brokerchannel.base.common.ChannelConstants;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * token操作类
 * <p>
 * fun makeToken 生成token<br>
 * fun getNewToken 获取新token<br>
 * fun verifyToken 验证token<br>
 * <p>
 * 
 * @author lu
 */
public class TokenOperate {

	/**
	 * @param token {@link Token} 创建token的请求对象
	 * @return {@link String} 创建token返回对象
	 * @throws UnsupportedEncodingException
	 * @throws JWTCreationException
	 * @throws IllegalArgumentException
	 * @方法描述:创建token
	 */
	public static String makeToken(Token token)
			throws IllegalArgumentException, JWTCreationException, UnsupportedEncodingException {
		token.setExpiresIn(new Date().getTime());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("alg", "HS256");
		map.put("typ", "JWT");
		String tokenStr = JWT.create().withHeader(map).withClaim(TokenConfig.NAME, JSON.toJSONString(token))
				.sign(Algorithm.HMAC256(TokenConfig.SECRET));// 加密
		return tokenStr;
	}
	
	public static void main(String[] args) throws IllegalArgumentException, UnsupportedEncodingException {
		verifyToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbiI6IntcImV4cGlyZXNJblwiOjE1MjQ2Mzg0OTk1MTIsXCJwYXNzd29yZFwiOlwiMTIzNDU2XCIsXCJzb3VyY2VcIjpcIjFcIixcInVzZXJuYW1lXCI6XCJEQTAwMDAwMVwifSJ9.4nbwf3aKll2ADNFEZRbXfkJzX2Uoe9dYmB4FkmUGV-g");
	}

	/**
	 * @param tokenstr {@link String} token解析的请求对象
	 * @return {@link Boolean} token解析返回对象
	 * @throws UnsupportedEncodingException
	 * @throws IllegalArgumentException
	 * @方法描述:token解析
	 */
	public static Boolean verifyToken(String tokenstr) throws IllegalArgumentException, UnsupportedEncodingException {
		JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TokenConfig.SECRET)).build();
		DecodedJWT jwt = verifier.verify(tokenstr);
		Map<String, Claim> claims = jwt.getClaims();
		Token token = JSONObject.parseObject(claims.get(TokenConfig.NAME).asString(), Token.class);
		ChannelConstants.SourceEnum[] sourceEnums = ChannelConstants.SourceEnum.values();
		long expiresInEnum = 0;
		for (ChannelConstants.SourceEnum sourceEnum : sourceEnums) {
			if (sourceEnum.code().equals(token.getSource())) {
				expiresInEnum = sourceEnum.expiresIn();
				break;
			}
		}
		long differsTime = (new Date().getTime() - token.getExpiresIn()) / TokenConfig.TIME;
		if (differsTime > expiresInEnum) {
			return true;
		}
		return false;
	}

	/**
	 * @param tokenstr {@link String} 获取一个新的token的请求对象
	 * @return {@link String} 获取一个新的token返回对象
	 * @throws UnsupportedEncodingException
	 * @throws JWTCreationException
	 * @throws IllegalArgumentException
	 * @方法描述:获取一个新的token
	 */
	public static String getNewToken(String tokenstr)
			throws IllegalArgumentException, JWTCreationException, UnsupportedEncodingException {
		JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TokenConfig.SECRET)).build();
		DecodedJWT jwt = verifier.verify(tokenstr);
		Map<String, Claim> claims = jwt.getClaims();
		Token token = JSONObject.parseObject(claims.get(TokenConfig.NAME).asString(), Token.class);
		return makeToken(token);
	}

}
